package com.wugh.fast.module.mapper.interceptor.plugin.impl;


import com.wugh.fast.module.mapper.EntityInfo;
import com.wugh.fast.module.mapper.interceptor.plugin.AbstractPlugin;

import java.util.Date;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Function;

/**
 * 说明: 自动处理gmt_create和gmt_modified时间字段
 * <pre>
 *     如果对象中字段为null,则自动赋予当前时间
 * </pre>
 *
 * @author wugh
 * @date 2018-09-25 17:12
 */
public class GMTCreateAndGMTModifiedPlugin extends AbstractPlugin {
    private static final String GMT_CREATE_COLUMN_NAME = "gmtCreate";
    private static final String GMT_MODIFIED_COLUMN_NAME = "gmtModified";
    private boolean containGmtCreate;
    private boolean containGmtModified;
    BiConsumer gmtCreateSetter;
    BiConsumer gmtModifiedSetter;
    Function gmtCreateGetter;
    Function gmtModifiedGetter;

    /**
     * 只有拥有gmtCreate或gmtModified字段时,才使用该插件
     *
     * @param entityInfo
     * @return
     */
    @Override
    public boolean support(EntityInfo entityInfo) {
        this.entityInfo = entityInfo;
        entityInfo.getEntityTable().getEntityClassColumns().forEach(entityColumn -> {
            if (entityColumn.getProperty().equals(GMT_CREATE_COLUMN_NAME)) {
                containGmtCreate = true;
                gmtCreateSetter = entityInfo.getPropertySetter(GMT_CREATE_COLUMN_NAME);
                gmtCreateGetter = entityInfo.getPropertyGetter(GMT_CREATE_COLUMN_NAME);
            } else if (entityColumn.getProperty().equals(GMT_MODIFIED_COLUMN_NAME)) {
                containGmtModified = true;
                gmtModifiedSetter = entityInfo.getPropertySetter(GMT_MODIFIED_COLUMN_NAME);
                gmtModifiedGetter = entityInfo.getPropertyGetter(GMT_MODIFIED_COLUMN_NAME);
            }
        });
        return containGmtCreate || containGmtModified;
    }

    /**
     * 更新时,只修改最后更新时间
     *
     * @param record
     */
    @Override
    public void autoHandleUpdateRecord(Object record) {
        if (containGmtModified) {
            Object gmtModified = gmtModifiedGetter.apply(record);
            if (gmtModified == null) {
                //用户没有指定最后修改时间
                gmtModifiedSetter.accept(record, new Date());
            }
        }
    }

    /**
     * 批量插入时,自动设置创建时间和最后修改时间
     *
     * @param recordList
     */
    @Override
    public void autoHandleInsertList(List recordList) {
        Date currentData = new Date();
        recordList.forEach(record -> {
            handleInsertRecord(currentData, record);
        });
    }

    /**
     * 处理单条数据
     *
     * @param currentData 当前时间
     * @param record      需要处理的对象
     */
    private void handleInsertRecord(Date currentData, Object record) {
        Object gmtCreate = null;
        if (containGmtCreate) {
            //有创建时间字段
            gmtCreate = gmtCreateGetter.apply(record);
            if (gmtCreate == null) {
                //用户没有指定创建时间,设置创建时间为当前时间
                gmtCreate = currentData;
                //设置
                gmtCreateSetter.accept(record, currentData);
            }
        }
        if (containGmtModified) {
            //有最后修改时间
            Object gmtModified = gmtModifiedGetter.apply(record);
            if (gmtModified == null) {
                //用户没有指定最后修改时间,最后修改时间去创建时间,如果没有创建时间取当前时间
                gmtModifiedSetter.accept(record, gmtCreate == null ? currentData : gmtCreate);
            }
        }
    }

    @Override
    public void autoHandleInsert(Object record) {
        handleInsertRecord(new Date(), record);
    }

    @Override
    public void autoHandleInsertSelective(Object record) {
        handleInsertRecord(new Date(), record);
    }
}
